from cached_math import CachedMath


def _generate_signs():
    while True:
        yield 1
        yield -1


def _generate_odd_numbers():
    value = 1
    while True:
        yield value
        value += 2


def s(x: float) -> float:
    math = CachedMath()
    ending = 1E-6
    result = 0
    for sign, factor in zip(_generate_signs(), _generate_odd_numbers()):
        upper = math.pow(x, factor)
        lower = math.factorial_slow(factor)
        item = sign * upper / lower
        result += item
        if abs(item) < ending:
            break
    return result
